// ignore_for_file: unused_local_variable

import 'package:get/get.dart';
import '../../app_views.dart';
import '../../data/models/calendar_day_info_model.dart';

/// 万年历逻辑控制器 - Calendar Logic Controller
///
/// 基于GetX最佳实践，管理万年历页面的状态和业务逻辑
/// Based on GetX best practices, manages calendar page state and business logic
class CalendarLogic extends GetxController {
  final ApiRepository _apiRepository = Get.find<ApiRepository>();

  /// 状态管理 - State management
  final state = Rx<CalendarState>(CalendarState(
    currentDate: DateTime.now(),
    selectedDate: DateTime.now(),
    currentMonth: DateTime.now(),
  ));

  @override
  void onInit() {
    super.onInit();
    // 初始化时加载当前月份数据 - Load current month data on initialization
    loadMonthData(state.value.currentMonth);
    loadSelectedDateInfo(state.value.selectedDate);
  }

  /// 选择日期 - Select date
  /// 选择指定日期并加载该日期的详细信息
  /// @param date 要选择的日期
  void selectDate(DateTime date) {
    state.value.selectedDate = date;

    loadSelectedDateInfo(date);

    // 如果选择的日期不在当前显示月份，切换月份
    // If selected date is not in current displayed month, switch month
    if (date.month != state.value.currentMonth.month ||
        date.year != state.value.currentMonth.year) {
      changeMonth(DateTime(date.year, date.month));
    }
  }

  /// 切换月份 - Change month
  /// 切换到指定月份并加载该月份的万年历数据
  /// @param month 要切换到的月份
  void changeMonth(DateTime month) {
    state.value.currentMonth = month;

    loadMonthData(month);
  }

  /// 上一个月 - Previous month
  /// 切换到上一个月
  void previousMonth() {
    final prevMonth = DateTime(
        state.value.currentMonth.year, state.value.currentMonth.month - 1);
    changeMonth(prevMonth);
  }

  /// 下一个月 - Next month
  /// 切换到下一个月
  void nextMonth() {
    final nextMonth = DateTime(
        state.value.currentMonth.year, state.value.currentMonth.month + 1);
    changeMonth(nextMonth);
  }

  /// 回到今天 - Go to today
  /// 选择今天的日期并切换到当前月份
  void goToToday() {
    final today = DateTime.now();
    selectDate(today);
    changeMonth(today);
  }

  /// 加载选中日期的详细信息 - Load selected date detailed information
  /// 从API获取指定日期的万年历详细信息，包括农历、节气、宜忌等
  /// @param date 要加载信息的日期
  /// @return Future<void> 异步操作完成标识
  /// @throws Exception 网络请求异常或数据解析异常
  Future<void> loadSelectedDateInfo(DateTime date) async {
    try {
      state.value.isLoading = true;

      final dateKey = _formatDateKey(date);

      // 如果缓存中有数据，直接使用 - Use cached data if available
      if (state.value.calendarData.containsKey(dateKey)) {
        await _updateStateWithDayInfo(date);
        return;
      }

      // 调用API获取日期信息 - Call API to get date information
      final dateString =
          '${date.year}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')}';
      final result = await _apiRepository.getCalendarInfo(dateString);

      if (result.success && result.data != null) {
        // 将CalendarInfo转换为CalendarDayInfo并缓存
        final calendarInfo = result.data!;
        final dayInfo = CalendarDayInfo(
          solarYear: date.year,
          solarMonth: date.month,
          solarDay: date.day,
          lunarYear: date.year,
          lunarMonth: calendarInfo.lunarDate.split('月')[0] + '月',
          lunarDay: calendarInfo.lunarDate.split('月').length > 1
              ? calendarInfo.lunarDate.split('月')[1]
              : calendarInfo.lunarDate,
          weekday: _getWeekdayName(date.weekday),
          constellation: calendarInfo.constellation,
          chineseZodiac: calendarInfo.zodiac,
          ganZhi: calendarInfo.ganzhi,
          solarTerm:
              calendarInfo.solarTerm.isEmpty ? null : calendarInfo.solarTerm,
          festivals: calendarInfo.festivals,
          lunarFestivals: calendarInfo.lunarFestivals,
          suitable: calendarInfo.yi,
          avoid: calendarInfo.ji,
          fiveElements: calendarInfo.fiveElements,
          nayin: calendarInfo.nayin,
          chong: '',
          sha: '',
        );

        final updatedCalendarData =
            Map<String, CalendarDayInfo>.from(state.value.calendarData);
        updatedCalendarData[dateKey] = dayInfo;

        state.value.selectedDayInfo = dayInfo;
      state.value.calendarData = updatedCalendarData;
      }
    } catch (e) {
      print('Error loading selected date info: $e');
      state.value.errorMessage = '获取日期信息失败: $e';
    } finally {
      state.value.isLoading = false;
    }
  }

  /// 加载月份万年历数据 - Load month calendar data
  /// 从API获取指定月份的万年历数据，用于月视图显示
  /// @param month 要加载数据的月份
  /// @return Future<void> 异步操作完成标识
  /// @throws Exception 网络请求异常或数据解析异常
  Future<void> loadMonthData(DateTime month) async {
    try {
      state.value.isLoadingMonth = true;

      // 调用API获取月份万年历数据 - Call API to get month calendar data
      final response = await _apiRepository.getMonthCalendarData(
        year: month.year,
        month: month.month,
      );

      if (response.success && response.data != null) {
        // 将MonthCalendarData转换为Map<String, CalendarDayInfo>格式
        final monthData = response.data!;
        final Map<String, CalendarDayInfo> dayInfoMap = {};

        for (final dayData in monthData.days) {
          final dateKey =
              '${monthData.year}-${monthData.month.toString().padLeft(2, '0')}-${dayData.day.toString().padLeft(2, '0')}';
          // 将DayCalendarData转换为CalendarDayInfo
          final calendarDayInfo = CalendarDayInfo(
            solarYear: monthData.year,
            solarMonth: monthData.month,
            solarDay: dayData.day,
            lunarYear: monthData.year, // 简化处理，实际应该从农历信息获取
            lunarMonth: dayData.calendarInfo.lunarDate.split('月')[0] + '月',
            lunarDay: dayData.calendarInfo.lunarDate.split('月').length > 1
                ? dayData.calendarInfo.lunarDate.split('月')[1]
                : dayData.calendarInfo.lunarDate,
            weekday: '', // 需要根据日期计算
            constellation: dayData.calendarInfo.constellation,
            chineseZodiac: dayData.calendarInfo.zodiac,
            ganZhi: dayData.calendarInfo.ganzhi,
            solarTerm: dayData.calendarInfo.solarTerm.isNotEmpty
                ? dayData.calendarInfo.solarTerm
                : null,
            festivals: dayData.calendarInfo.festivals,
            lunarFestivals: dayData.calendarInfo.lunarFestivals,
            suitable: dayData.calendarInfo.yi,
            avoid: dayData.calendarInfo.ji,
            fiveElements: dayData.calendarInfo.fiveElements,
            nayin: dayData.calendarInfo.nayin,
            chong: '', // 需要从API获取
            sha: '', // 需要从API获取
          );

          dayInfoMap[dateKey] = calendarDayInfo;
        }

        // 更新状态中的万年历数据
        final updatedCalendarData =
            Map<String, CalendarDayInfo>.from(state.value.calendarData);
        updatedCalendarData.addAll(dayInfoMap);

        state.value.calendarData = updatedCalendarData;
      }
    } catch (e) {
      print('Error loading month data: $e');
      state.value.errorMessage = '获取月份数据失败: $e';
    } finally {
      state.value.isLoadingMonth = false;
    }
  }

  /// 刷新数据 - Refresh data
  /// 清除缓存并重新加载当前月份和选中日期的数据
  /// @return Future<void> 异步操作完成标识
  Future<void> refresh() async {
    state.value.calendarData = {};

    await Future.wait([
      loadMonthData(state.value.currentMonth),
      loadSelectedDateInfo(state.value.selectedDate),
    ]);
  }

  /// 更新状态 - Update state with day info
  Future<void> _updateStateWithDayInfo(DateTime date) async {
    try {
      final dateKey = _formatDateKey(date);

      // 先从缓存中查找 - First look in cache
      if (state.value.calendarData.containsKey(dateKey)) {
        state.value.selectedDayInfo = state.value.calendarData[dateKey];
        return;
      }

      // 如果缓存中没有，调用API获取 - If not in cache, call API
      final result = await _apiRepository.getCalendarInfo(dateKey);

      if (result.success && result.data != null) {
        // 将CalendarInfo转换为CalendarDayInfo
        final calendarInfo = result.data!;
        final dayInfo = CalendarDayInfo(
          solarYear: date.year,
          solarMonth: date.month,
          solarDay: date.day,
          lunarYear: date.year, // 这里需要根据实际农历年份调整
          lunarMonth: calendarInfo.lunarDate.split('月')[0],
          lunarDay: calendarInfo.lunarDate.split('月')[1],
          weekday: _getWeekdayName(date.weekday),
          constellation: calendarInfo.constellation,
          chineseZodiac: calendarInfo.zodiac,
          ganZhi: calendarInfo.ganzhi,
          solarTerm:
              calendarInfo.solarTerm.isEmpty ? null : calendarInfo.solarTerm,
          festivals: calendarInfo.festivals,
          lunarFestivals: calendarInfo.lunarFestivals,
          suitable: calendarInfo.yi,
          avoid: calendarInfo.ji,
          fiveElements: calendarInfo.fiveElements,
          nayin: calendarInfo.nayin,
          chong: '',
          sha: '',
        );

        final updatedCalendarData =
            Map<String, CalendarDayInfo>.from(state.value.calendarData);
        updatedCalendarData[dateKey] = dayInfo;

        state.value.selectedDayInfo = dayInfo;
      state.value.calendarData = updatedCalendarData;
      }
    } catch (e) {
      print('获取日期信息失败: $e');
    }
  }

  /// 获取星期名称 - Get weekday name
  String _getWeekdayName(int weekday) {
    const weekdays = ['一', '二', '三', '四', '五', '六', '日'];
    return '星期${weekdays[weekday - 1]}';
  }

  /// 格式化日期键 - Format date key
  String _formatDateKey(DateTime date) {
    return '${date.year}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')}';
  }

  /// 检查日期是否在当前月份 - Check if date is in current month
  /// 用于日历视图中判断日期是否属于当前显示的月份
  /// Used in calendar view to determine if date belongs to currently displayed month
  bool isInCurrentMonth(DateTime date) {
    return date.year == state.value.currentMonth.year &&
        date.month == state.value.currentMonth.month;
  }

  /// 检查是否为今天 - Check if it's today
  /// 用于日历视图中高亮显示今天的日期
  /// Used in calendar view to highlight today's date
  bool isToday(DateTime date) {
    final today = DateTime.now();
    return date.year == today.year &&
        date.month == today.month &&
        date.day == today.day;
  }

  /// 检查日期是否被选中 - Check if date is selected
  /// 用于日历视图中显示选中状态
  /// Used in calendar view to show selected state
  bool isSelected(DateTime date) {
    return date.year == state.value.selectedDate.year &&
        date.month == state.value.selectedDate.month &&
        date.day == state.value.selectedDate.day;
  }

  /// 获取指定月份的所有日期 - Get all dates for specified month
  /// 用于日历视图中生成月份的日期网格
  /// Used in calendar view to generate date grid for month
  List<DateTime> getMonthDates(DateTime month) {
    final firstDay = DateTime(month.year, month.month, 1);
    final lastDay = DateTime(month.year, month.month + 1, 0);

    // 获取第一天是星期几（0=周日，1=周一...）
    final firstWeekday = firstDay.weekday % 7;

    // 计算需要显示的开始日期（包含上个月的尾部日期）
    final startDate = firstDay.subtract(Duration(days: firstWeekday));

    // 生成42天的日期（6周 x 7天）
    final dates = <DateTime>[];
    for (int i = 0; i < 42; i++) {
      dates.add(startDate.add(Duration(days: i)));
    }

    return dates;
  }

  /// 获取日期信息 - Get day info
  CalendarDayInfo? getDayInfo(DateTime date) {
    final key =
        '${date.year}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')}';
    return state.value.dayInfoCache[key] ?? state.value.calendarData[key];
  }
}
